package com.ccys.app.service.impl;

import com.ccys.app.service.MemberVietnamConsultService;
import com.ccys.common.constants.Constants;
import com.ccys.common.constants.CoreAppConstants;
import com.ccys.common.third.aws.s3.S3Util;
import com.ccys.common.third.mailGun.MailgunUtil;
import com.ccys.common.util.HtmlUtils;
import com.ccys.common.util.Kit;
import com.ccys.common.util.StringUtil;
import com.ccys.common.vo.ResponseResultApp;
import com.ccys.db.cache.UserUtil;
import com.ccys.db.dto.CommonDto;
import com.ccys.db.dto.member.*;
import com.ccys.db.entity.*;
import com.ccys.db.mapper.*;
import com.ccys.db.page.AppPageDto;
import com.ccys.db.rely.service.impl.BaseServiceImpl;
import com.ccys.db.service.BaseSysCodeService;
import com.ccys.db.vo.member.*;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


@Slf4j
@Service
public class MemberVietnamConsultServiceImpl extends BaseServiceImpl<TblMember> implements MemberVietnamConsultService {

    @Autowired(required = false)
    private TblMemberMapper memberMapper;
    private static Lock lock = new ReentrantLock();
    @Autowired(required = false)
    private BaseSysCodeService baseSysCodeService;

    @Autowired(required = false)
    private TblDoctorMapper tblDoctorMapper;

    @Autowired(required = false)
    private TblBookingMapper tblBookingMapper;


    @Autowired(required = false)
    private TblClinicMapper tblClinicMapper;
    @Autowired(required = false)
    private TblBookingFeeMapper tblBookingFeeMapper;

    @Autowired(required = false)
    private TblLabResultMapper tblLabResultMapper;

    @Autowired(required = false)
    private TblMemberAllergiesMapper tblMemberAllergiesMapper;

    @Autowired(required = false)
    private TblProductMapper tblProductMapper;
    @Autowired(required = false)
    private TblMemberFamilyMapper memberFamilyMapper;

    @Autowired(required = false)
    private TblPaymentMethodsMapper tblPaymentMethodsMapper;

    @Resource
    private TblPharmacyOperatingHoursMapper tblPharmacyOperatingHoursMapper;

    @Resource
    private TblPharmacyMapper tblPharmacyMapper;

    @Resource
    private TblBookingPaymentPhotoMapper tblBookingPaymentPhotoMapper;
    @Resource
    private TblBookingPaymentMapper tblBookingPaymentMapper;



    @Override
    public ResponseResultApp getDeliveryAddressInfo(CommonDto dto) {
        TblMember curLoginMember = UserUtil.getCurLoginMember();
        dto.setId(curLoginMember.getId());
        dto.setTimezone(CoreAppConstants.DEFAULT_TIMEZONE);
        AppPageDto.startPage();
        List<DeliveryAddressInfoVO> list =  this.memberMapper.getDeliveryAddressInfo(dto);
        PageInfo<DeliveryAddressInfoVO> pageInfo = new PageInfo<>(list);
        DeliveryAddressInfoPageVO vo = new DeliveryAddressInfoPageVO();
        vo.setAddressInfoVOList(list);
        vo.setTotalPage(pageInfo.getPages());
        return ResponseResultApp.success(vo);
    }

    @Override
    public ResponseResultApp getBookingPharmacyForSelfPickUp(BookingPharmacyForSelfPickUpDto dto) {
        TblBooking tblBooking = this.tblBookingMapper.selectByPrimaryKey(dto.getBooking_id());
        if(tblBooking == null) {
            return ResponseResultApp.error("TblBooking TblBooking");
        }
        TblMember curLoginMember = UserUtil.getCurLoginMember();
        //原 就写死  245 --VietNam  该接口只有越南在使用
        dto.setCountry_id("245");
        dto.setMem_id(curLoginMember.getId());
        TblPharmacy ts = new TblPharmacy();
        ts.setCountryId(dto.getCountry_id());
        BookingPharmacyForSelfPickUpVO bookingPharmacyForSelfPickUpVO = this.tblPharmacyMapper.getCountryTblPharmacyTop1(ts);
        if(bookingPharmacyForSelfPickUpVO != null) {
            Integer collectionDay = bookingPharmacyForSelfPickUpVO.getCollectionDay();
            if(collectionDay != null) {
                String timeZone = tblBooking.getBookingTimeZone();
                if(StringUtil.isEmpty(timeZone)) {
                    timeZone = "+00:00";
                }
                try {
                    bookingPharmacyForSelfPickUpVO.setCollectionDateTimeUtc(Kit.timestampAddDayTimeZone(System.currentTimeMillis(), collectionDay, timeZone).toString());
                    bookingPharmacyForSelfPickUpVO.setCollectionDateTime(Kit.formatDateTime(new Date(Long.parseLong(bookingPharmacyForSelfPickUpVO.getCollectionDateTimeUtc())),"yyyy-MM-dd HH:mm:ss"));
                }catch (Exception e) {
                    e.printStackTrace();
                }

            }

        }
        //查询药房营业时间
        List<OperatingHoursVO> hoursList =  this.tblPharmacyOperatingHoursMapper.getPharmacyOperatingHoursList(bookingPharmacyForSelfPickUpVO.getPharmacyId());
        bookingPharmacyForSelfPickUpVO.setOperatingHours(hoursList);
        return ResponseResultApp.success(bookingPharmacyForSelfPickUpVO);
    }

    @Override
    public ResponseResultApp getPaymentInstruction(PaymentInstructionDto dto) {
        PaymentInstructionVO paymentInstructionVO = new PaymentInstructionVO();
        List<PaymentMethodVO> paymentMethods  = this.tblBookingMapper.getPaymentMethodVO(dto);
        paymentInstructionVO.setPaymentMethods(paymentMethods);
        return ResponseResultApp.success(paymentInstructionVO);
    }

    @Override
    public ResponseResultApp updatePaymentScreenForDelivery(UpdatePaymentScreenForDeliveryDto dto) {
        if(StringUtil.isEmpty(dto.getBank_id()) || StringUtil.isEmpty(dto.getBank_id())) {
            return ResponseResultApp.error("Parameter not passed");
        }
        TblPaymentMethods tblPaymentMethods = this.tblPaymentMethodsMapper.selectByPrimaryKey(dto.getBank_id());
        if(tblPaymentMethods == null) {
            return ResponseResultApp.error("Parameter bank_id not passed");
        }
        TblBooking tblBooking = this.tblBookingMapper.selectByPrimaryKey(dto.getBooking_id());
        if(tblBooking == null) {
            return ResponseResultApp.error("Parameter booking_id not passed");
        }
        TblMember patient = this.memberMapper.selectByPrimaryKey(tblBooking.getPatientMemId());
        if(patient == null) {
            return ResponseResultApp.error("booking  patient not absent");
        }
        String patientName = "";
        if(patient != null){
            if(StringUtil.isNotEmpty(patient.getLastName())) {
                patientName = patient.getFirstName() + patient.getLastName();
            }else {
                patientName = patient.getFirstName();
            }
        }
        tblBooking.getPatientMemId();
        TblPharmacy tblPharmacyWhere = new TblPharmacy();
        //源逻辑
        tblPharmacyWhere.setGroupId("245");
        tblPharmacyWhere.setStatus(1);
        String pharmacy_email = "";
        String pharmacy_name = "";
        String pharmacy_collect_by = "";
        List<TblPharmacy> select = this.tblPharmacyMapper.select(tblPharmacyWhere);
        if(select != null && !select.isEmpty()) {
            TblPharmacy tblPharmacy = select.get(0);
            pharmacy_email = tblPharmacy.getEmail();
            pharmacy_name = tblPharmacy.getName();
            pharmacy_collect_by = tblPharmacy.getCollectionDay() == null ? null : tblPharmacy.getCollectionDay().toString();
        }
        TblBookingFee whereBookingFee = new TblBookingFee();
        whereBookingFee.setBookingId(tblBooking.getId());
        List<TblBookingFee> selectFee = this.tblBookingFeeMapper.select(whereBookingFee);
        TblBookingFee tblBookingFee = null;
        BigDecimal total_amount = BigDecimal.ZERO;
        if(selectFee != null && !selectFee.isEmpty()) {
            tblBookingFee = selectFee.get(0);
            if(tblBookingFee.getBenefits() != null) {
                total_amount = tblBookingFee.getTotalAmount().subtract(tblBookingFee.getBenefits());
            }else{
                total_amount = tblBookingFee.getTotalAmount();
            }
        }
        //1:paid by nets
        Integer paymentType = 1;
        if("cash".equals(tblPaymentMethods.getType())) {
            //2:paid by cash
            paymentType = 2;
        }
        TblMember curLoginMember = UserUtil.getCurLoginMember();
        String currentCountry = tblBooking.getPatientCountryOfResidence();
        if("106".equals(currentCountry)) {
            //Indo SP  印度尼西亚全科 3:paid by debit or credit
            paymentType = 3;

        }else if("41".equals(currentCountry)) {
            //当前国家固定使用支付类型
            paymentType = 2;

        }
        //更新支付方式
        TblBookingPayment tblBookingPayment = new TblBookingPayment();
        tblBookingPayment.setPaymentMethod(String.valueOf(paymentType));
        tblBookingPayment.setUpdatedOnUtc(System.currentTimeMillis());
            Example example = new Example(TblBookingPayment.class);
            		example.createCriteria().andCondition("booking_id='"+dto.getBank_id()+"'");
        this.tblBookingPaymentMapper.updateByExampleSelective(tblBookingPayment,example);
        //邮件模版源码  public static string API_EMAIL_PATIENT_SELECT_MEDICATION = "~/emailTemplate/EmailPatientSelectMedication.txt";
        //现金支付且配送类型为2  发送电子邮件 TODO 没有配送类型字段
        if(paymentType == 2 && "2".equals("tblBooking.booking_delivery_type")) {
            String finalPharmacy_name = pharmacy_name;
            String finalPharmacy_collect_by = pharmacy_collect_by;
            String finalPatientName = patientName;
            BigDecimal finalTotal_amount = total_amount;
            CompletableFuture.runAsync(() -> {
                try {
                    //发送给病人
                    String sContent = HtmlUtils.getTemplateContent("EmailPatientSelectMedication.ftl", null);
                    sContent = sContent.replace("[pharmacy_name]", finalPharmacy_name);
                    sContent = sContent.replace("[booking_code]", tblBooking.getConsultationNo());
                    sContent = sContent.replace("[member_name]", finalPatientName);
                    sContent = sContent.replace("[member_nric_fin]", patient.getNricFin());
                    sContent = sContent.replace("[total_amount]", finalTotal_amount.toString());
                    sContent = sContent.replace("[pharmacy_collect_by]", finalPharmacy_collect_by);
                    MailgunUtil.sendEmail(curLoginMember.getEmail(), "Consultation {booking_code} - {email_subject}", null, sContent);

                } catch (Exception e) {
                    log.error(e.getMessage());
                }
            });
        }
        //TODO 返回方法  GetBookingInfoWithTimezone(string account_id, string booking_id, string account_type, string timezone, string requestfrom, bool qrCode = false, int is_rebuy = 0, string card_id = null, string card_code = null, bool fromCache = false)
        return ResponseResultApp.success();
    }

    @Override
    public ResponseResultApp uploadPaymentPhoto(HttpServletRequest request, UploadPaymentPhotoDto dto) {
        if(StringUtil.isEmpty(dto.getBooking_id())) {
            return ResponseResultApp.error("Parameter booking_id not passed");
        }
        TblBooking tblBooking = this.tblBookingMapper.selectByPrimaryKey(dto.getBooking_id());
        if(tblBooking == null) {
            return ResponseResultApp.error("Parameter booking_id not passed");
        }
        TblBookingFee whereBookingFee = new TblBookingFee();
        whereBookingFee.setBookingId(tblBooking.getId());
        List<TblBookingFee> select = this.tblBookingFeeMapper.select(whereBookingFee);
        TblBookingFee tblBookingFee = null;
        BigDecimal total_amount = BigDecimal.ZERO;
        if(select != null && !select.isEmpty()) {
            tblBookingFee = select.get(0);
            if(tblBookingFee.getBenefits() != null) {
                total_amount = tblBookingFee.getTotalAmount().subtract(tblBookingFee.getBenefits());
            }else{
                total_amount = tblBookingFee.getTotalAmount();
            }
        }


        TblClinic tblClinic = this.tblClinicMapper.selectByPrimaryKey(tblBooking.getClinicId());
        TblMember patient = this.memberMapper.selectByPrimaryKey(tblBooking.getPatientMemId());
        if(patient == null) {
            return ResponseResultApp.error("patient  absent");
        }
        TblDoctor tblDoctor = this.tblDoctorMapper.selectByPrimaryKey(tblBooking.getDoctorId());
        String doctor_name = "";
        if(tblDoctor != null) {
            doctor_name = tblDoctor.getFirstName();
            if(StringUtil.isNotEmpty(tblDoctor.getLastName())) {
                doctor_name  = doctor_name + tblDoctor.getLastName();
            }
        }
        CommonsMultipartResolver mutilpartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        String folder_code = Constants.S3_Folder.LOG_TRANSACTION + "/" + dto.getBooking_id() + "/";
        String fileName = folder_code + Kit.get32UUID().replace("-", "");
        if (mutilpartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> it = multiRequest.getFileNames();
            while (it.hasNext()) {
                String textName = it.next();
                // 获取MultipartFile类型文件
                List<MultipartFile> fileList = multiRequest.getFiles(textName);
                try{
                    for(MultipartFile fileDetail:fileList) {
                        InputStream in = fileDetail.getInputStream();
                        String[] fileNames = fileDetail.getOriginalFilename().split("\\.");
                        fileName = fileName + "." + fileNames[fileNames.length - 1];
                        //通过字节数组上传
                        S3Util.putS3ObjectByByte(S3Util.bucketName, fileName,fileDetail.getBytes());

                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }



        }
        //删除已上传的问诊支付信息
        TblBookingPayment tblBookingPaymentDelete = new TblBookingPayment();
        tblBookingPaymentDelete.setDelFlag(1);
        Example example = new Example(TblBookingPayment.class);
        		example.createCriteria().andCondition("del_flag=0")
                .andCondition("status = 1").andCondition("booking_id = '"+dto.getBooking_id()+"'");
        this.tblBookingPaymentMapper.updateByExampleSelective(tblBookingPaymentDelete,example);
        //保存  问诊支付信息、记录 tbl_Booking_CyberSource  TODO 原保存字段都为空，数据怎么进入表的
        TblBookingPayment tblBookingPayment = new TblBookingPayment();
        tblBookingPayment.setBookingId(dto.getBooking_id());
        tblBookingPayment.setUpdatedOnUtc(System.currentTimeMillis());
        tblBookingPayment.setPaymentMethod("2");
        this.tblBookingPaymentMapper.insert(tblBookingPayment);
        //保存问诊支付记录图片 tbl_booking_payment_photo
        TblBookingPaymentPhoto tblBookingPaymentPhoto = new TblBookingPaymentPhoto();
        tblBookingPaymentPhoto.setPhoto(fileName);
        tblBookingPaymentPhoto.setCybersourceId(tblBookingPayment.getId());
        this.tblBookingPaymentPhotoMapper.insert(tblBookingPaymentPhoto);

        if("106".equals(tblBooking.getPatientCountryOfResidence())) {
            //Update tbl_Booking
            TblBooking tblBookingUpdate = new TblBooking();
            tblBookingUpdate.setAppointmentStatus(1);
            tblBookingPayment.setPaymentMethod(null);
            tblBookingUpdate.setUpdatedOnUtc(System.currentTimeMillis());
            tblBookingUpdate.setId(dto.getBooking_id());
            this.tblBookingMapper.updateByPrimaryKeySelective(tblBookingUpdate);
        }
        String sendEmail = this.baseSysCodeService.getCodeValue("Trigger_Email_CA_Uploaded_Proof_Of_Payment_VN", null);
        if("41".equals(tblBooking.getPatientCountryOfResidence())) {
            sendEmail = this.baseSysCodeService.getCodeValue("Trigger_Email_CA_Uploaded_Proof_Of_Payment_Cambodia", null);
        }

        String clinicName =  "";
        String childName = "";
        if(tblClinic != null) {
            clinicName = tblClinic.getName();
        }
        if(patient != null) {
            childName = patient.getFirstName();
            if(StringUtil.isNotEmpty(patient.getLastName())) {
                childName = childName +" "+ patient.getLastName();
            }
        }
        String status = "Pending";
        String confirmURL = "appUrl" + "/v1/Appointment/Confirm?booking_id=" + tblBooking.getId();
        String title = "You have pending appointment booking request(s):";
        String sSubject = "WhiteCoat "+ clinicName +" Pending Appointment - Action Required";
        if (status == "Rescheduled") {
            sSubject = "WhiteCoat {clinic_name} Rescheduled Appointment";
            title = "You have a rescheduled appointment booking:";
        }
        // Indo SP
        if (Constants.COUNTRY_INDONESIA_ID.equals(tblBooking.getPatientCountryOfResidence()))  {
            try {
                String templateContent = HtmlUtils.getTemplateContent("Indo_SP_EmailPendingAppointment.ftl", null);
                templateContent = templateContent.replace("[clinic_name]", "xxx");
                templateContent = templateContent.replace("[title]", title);
                templateContent = templateContent.replace("[booking_code]", tblBooking.getConsultationNo());
                templateContent = templateContent.replace("[clinic_name]", clinicName);
                templateContent = templateContent.replace("[patient_name]", childName);
                templateContent = templateContent.replace("[age]", Kit.getAge(patient.getDob()) + "");
                templateContent = templateContent.replace("[gender]", patient.getGender() + "");
                templateContent = templateContent.replace("[doctor_name]", doctor_name);
                templateContent = templateContent.replace("[appointment_date]", tblBooking.getAppointmentCreatedOn()== null?"":Kit.formatDateTime(tblBooking.getAppointmentCreatedOn(),"yyyy-MM-dd HH:mm:ss"));
                templateContent = templateContent.replace("[appointment_start_time]", tblBooking.getAppointmentTime()== null?"":Kit.formatDateTime(tblBooking.getAppointmentTime(),"yyyy-MM-dd HH:mm:ss"));
                templateContent = templateContent.replace("[appointment_end_time]", tblBooking.getAppointmentEndTime()== null?"":Kit.formatDateTime(tblBooking.getAppointmentEndTime(),"yyyy-MM-dd HH:mm:ss"));
                if (StringUtil.isNotEmpty(childName)) {
                    templateContent = templateContent.replace("[patient_name_text]", "Parent name");
                    templateContent = templateContent.replace("[child_name]", childName);
                    templateContent = templateContent.replace("[display_child_section]", "block");

                } else {
                    templateContent = templateContent.replace("[patient_name_text]", "Patient name");
                    templateContent = templateContent.replace("[display_child_section]", "none");
                }
                if ("Rescheduled".equalsIgnoreCase(status)) {
                    templateContent = templateContent.replace("[display_appointment_pending]", "none");
                }
                else {
                    templateContent = templateContent.replace("[display_appointment_pending]", "block");
                    templateContent = templateContent.replace("[confirm_url]", confirmURL);
                }
                //异步处理邮件发送业务
                String finalSendEmail = sendEmail;
                String finalTemplateContent = templateContent;
                String finalClinicName = clinicName;
                String finalSSubject = sSubject;
                CompletableFuture.runAsync(() -> {
                    MailgunUtil.sendEmail(finalSendEmail, finalSSubject,null, finalTemplateContent);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            try {
                String templateContent = HtmlUtils.getTemplateContent("EmailPatientUploadedProofOfPayment.ftl", null);
                templateContent = templateContent.replace("[clinic_name]", clinicName);
                templateContent = templateContent.replace("[hi_name]", "CMS Admin");
                templateContent = templateContent.replace("[booking_code]", tblBooking.getConsultationNo());
                templateContent = templateContent.replace("[member_name]", childName);
                templateContent = templateContent.replace("[member_nric_fin]", patient.getNricFin());
                templateContent = templateContent.replace("[total_amount]", total_amount.toString());
                //异步处理邮件发送业务
                String finalSendEmail = sendEmail;
                String finalTemplateContent = templateContent;
                CompletableFuture.runAsync(() -> {
                    MailgunUtil.sendEmail(finalSendEmail, "Consultation "+tblBooking.getConsultationNo()+" - WhiteCoat Bank Transfer",null, finalTemplateContent);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        dto.setFile(null);
        return ResponseResultApp.success(dto);
    }
}